function [modulated_signal,norm_constellation, intg]= WiSiL_Tx_modulator(bits_tx,modulation)

%MODULATOR outputs a column vector whith complex modulated symbols. 
%   This function modulates a binary vector, obtaining complex modulated 
%   symbols, according to digital modulation type and bit energy informed.
%   The size of constellation "M" is an external parameter.
%
%
% Syntax:
%   modulated_signal = Modulation(bits_tx, modulation)
%       INPUT:
%       bits_tx is the binary column vector to be modulated
%       modulation is a structure defined in Simulation_Settings
% 
%       PARAMETERS:
%       modulation.M = Constelation Size
%       modulation.type = 'QAM' or 'PSK'
%
%       OUTPUT:
%       The output modulated_signal is a column vector, which size is determined
%       by the size of the binary vector to be modulated, and by the number of 
%       bits per modulated symbol, which is an extern parameter. 
%       

% 14/07/2008
% Erika Portela
% Insert structure "modulation" 
% Remove "Settings.m"


wordSize = log2(modulation.M);
Es = 1;

intg = [0:modulation.M - 1].';
ini_phase = 0;
Kmod = 1;
switch modulation.type
    case 'QAM'        
        switch modulation.M
            case 16                
                %LTE
                mapping = [9 8 13 12 10 11 14 15 5 4 1 0 6 7 2 3].';
                Kmod = 1/sqrt(10);
            case 64
                %LTE
                mapping = [42 43 34 35 41 40 33 32 50 51 58 59 49 48 57 56 45 44 37 36 46 47 38 39 53 52 61 60 54 55 62 63 18 19 26 27 17 16 25 24 10 11 2 3 9 8 1 0 21 20 29 28 22 23 30 31 13 12 5 4 14 15 6 7].';                
                Kmod = 1/sqrt(42);
            otherwise
                error('Choose a valid bit/symbol value: 16-QAM or 64-QAM');
        end   
        intgray = mapping(intg + 1);
        norm_constellation = sqrt(Es)*Kmod*qammod(intgray, modulation.M);
        
    case 'PSK'                
        switch modulation.M
            case 2
                mapping = [0 1].';                                 
            case 4
                %LTE
                mapping = [0 3 1 2].';                                                             
                Kmod = 1/sqrt(2);
                ini_phase = pi/4;
            otherwise
                error('Choose a valid bit/symbol value: BPSK or QPSK');
        end        
        intgray = mapping(intg + 1);
        norm_constellation = sqrt(Es)*pskmod(mapping, modulation.M, ini_phase);
        
    otherwise
        error('Choose a valid modulation type');
end

%Group encoded_bits in groups with wordSize bits
num_mod_symbols = length(bits_tx)/wordSize;
bit_group = reshape(bits_tx,wordSize,num_mod_symbols).';
modulated_signal_fill = zeros(num_mod_symbols,1);

%Modulation according to parameter "modulation" set in parameters archive
switch modulation.type
    case 'QAM'
        %modulated_signal = sqrt(Es)*Kmod*qammod(integer_tx,M);
        switch modulation.M
            case 16
                for n=1:num_mod_symbols
                    b3 = bit_group(n,1);
                    b2 = bit_group(n,2);
                    b1 = bit_group(n,3);
                    b0 = bit_group(n,4);
                    modulated_signal_fill(n,1) = sqrt(Es)*Kmod*((1-2*b3)*(1+2*b1) + j*(1-2*b2)*(1+2*b0));
                end
            case 64
                for n=1:num_mod_symbols
                    b5 = bit_group(n,1);
                    b4 = bit_group(n,2);
                    b3 = bit_group(n,3);
                    b2 = bit_group(n,4);
                    b1 = bit_group(n,5);
                    b0 = bit_group(n,6);
                    modulated_signal_fill(n,1) = sqrt(Es)*Kmod*((2*b5-1)*((1-2*b3)*(1+2*b1)-4) + j*((2*b4-1)*((1-2*b2)*(1+2*b0)-4)));
                end
        end %end switch M for QAM modulation
            
    case 'PSK'
        switch modulation.M
            case 2
                for n=1:num_mod_symbols
                    b0 = bit_group(n,1);
                    modulated_signal_fill(n,1) = sqrt(Es)*Kmod*(1-2*b0);
                end
                
            case 4
                for n=1:num_mod_symbols
                    b1 = bit_group(n,1);
                    b0 = bit_group(n,2);
                   modulated_signal_fill(n,1) = sqrt(Es)*Kmod*((1-2*b1)+j*(1-2*b0));
                end
        end %end switch M for PSK modulation

end %end switch modulation

modulated_signal = modulated_signal_fill;
